package com.ic.util;

import com.google.common.collect.Lists;
import com.ic.domain.Rule;
import org.apache.commons.lang.StringUtils;

import java.util.Arrays;
import java.util.List;

public class DrlUtil {
    private static final String HEADER = "import com.ic.domain.Notify;\n" +
            "import com.ic.domain.Device;\n" +
            "import org.quartz.CronExpression\n" +
            "import java.util.Date;\n" +
            "import com.ic.common.RuleContext;\n" +
            "import java.util.List;\n" +
            "dialect \"mvel\"\n" +
            "global com.ic.service.RuleAction ruleAction;\n" +
            "global com.ic.common.DroolsContainer droolsContainer;\n" +
            "\n" +
            "function boolean checkCorn(String corn){\n" +
            "    CronExpression cronExpression = new CronExpression(corn);\n" +
            "    return !cronExpression.isSatisfiedBy(new Date());\n" +
            "}\n" +
            "\n";

    private static final String RULE_END = "then\n" +
            "    droolsContainer.triggered($rc);\n" +
            "    droolsContainer.matched($rc);\n" +
            "    ruleAction.doAction($notify, \"\");\n" +
            "then [matched]\n" +
            "    droolsContainer.matched($rc);\n" +
            "    System.out.println(\"Matched ...\");\n" +
            "then [doNothing]\n" +
            "end";

    public static String drl(List<Rule> rules) {
        StringBuilder sb = new StringBuilder(HEADER);
        rules.forEach(r -> {
            sb.append("rule \"").append(r.getName()).append("\"\n");
            sb.append("when\n");
            sb.append("\t$notify: Notify()\n");
            sb.append("\t$rcs: List()\n");
            sb.append("\t$rc: RuleContext(id == \"").append(r.getId()).append("\") from $rcs\n");
            sb.append(convert(r.getExpression())).append("\n");
            sb.append("if(checkCorn(\"").append(r.getCorn()).append("\")) break[doNothing]\n");
            sb.append(RULE_END).append("\n\n");
        });
        return sb.toString();
    }

    private static String convert(String expression) {
        String ret = Arrays.stream(expression.split("\n"))
                .filter(StringUtils::isNotBlank)
                .reduce((s1, s2) -> s1 + "\n\t" + s2.replace("\t", "")).orElse("");
        return "\t" + ret;
    }

    public static void main(String[] args) {
        List<Rule> list = Lists.newArrayList();
        Rule rule = new Rule();
        rule.setId("1");
        rule.setName("rule1");
        rule.setExpression("if($rc.triggerNum > 6) break [matched]\n" +
                "if($rc.matchNum < 2) break [matched]\n" +
                "if(!checkCorn(\"\")) break[doNothing]\n");
        list.add(rule);

        rule = new Rule();
        rule.setId("2");
        rule.setName("rule2");
        rule.setExpression("if($rc.triggerNum > 6) break [matched]\n" +
                "if($rc.matchNum < 2) break [matched]\n" +
                "if(!checkCorn(\"\")) break[doNothing]\n");
        list.add(rule);

        System.out.println(drl(list));
    }
}
